package com.taxi.driver.module.amap;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.navi.AMapNavi;
import com.amap.api.navi.AMapNaviView;
import com.amap.api.navi.AMapNaviViewOptions;
import com.amap.api.navi.enums.AimLessMode;
import com.amap.api.navi.enums.NaviType;
import com.amap.api.navi.model.AMapNaviLocation;
import com.amap.api.navi.model.NaviInfo;
import com.amap.api.navi.model.NaviLatLng;
import com.qianxx.utils.RxUtil;
import com.socks.library.KLog;
import com.taxi.driver.BuildConfig;
import com.taxi.driver.R;
import com.taxi.driver.data.entity.Car;
import com.taxi.driver.data.user.UserRepository;
import com.taxi.driver.event.MapEvent;
import com.taxi.driver.module.amap.assist.MapUtils;
import com.taxi.driver.module.amap.dagger.ANavigateModule;
import com.taxi.driver.module.amap.dagger.DaggerANavigateComponent;

import org.greenrobot.eventbus.EventBus;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.ButterKnife;
import rx.Observable;
import rx.Subscription;

/**
 * 功能描述：导航地图层
 */
public class ANavigateFragment extends ANavigateBaseFragment implements ANavigateContract.View {

    public static ANavigateFragment newInstance() {
        return new ANavigateFragment();
    }

    @Inject
    ANavigatePresenter mPresenter;
    @Inject
    UserRepository mUserRepository;

    @BindView(R.id.navi_view)
    AMapNaviView mAMapNaviView;

    private AMap mAMap;
    private AMapNavi mAMapNavi;

    protected final List<NaviLatLng> sList = new ArrayList<>();
    protected final List<NaviLatLng> eList = new ArrayList<>();

    private int mTop;
    private int mBottom;
    private boolean mIsNaviInited;

    LatLng mNaviOrigin; //导航起点
    LatLng mNaviDest; //导航终点

    LatLng mOrderOrigin; //订单起点
    LatLng mOrderDest; //订单终点

    private float curAngle;//司机当前角度
    private boolean isCycle;//是否是循环状态
    private boolean mEmulator; //是否开启模拟导航
    private MapUtils mMapUtils;
    private Subscription mSubscribe;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mView = inflater.inflate(R.layout.fragment_anavigate, container, false);
        ButterKnife.bind(this, mView);

        mMapUtils = new MapUtils();
        initView(savedInstanceState);
        mPresenter.onCreate();
        return mView;
    }

    private void initView(Bundle savedInstanceState) {
        mAMapNavi = AMapNavi.getInstance(getContext().getApplicationContext());
        mAMapNavi.addAMapNaviListener(this);
        mAMapNavi.setEmulatorNaviSpeed(100);

        mAMapNaviView.onCreate(savedInstanceState);
        mAMapNaviView.setAMapNaviViewListener(this);
        if (mAMap == null) {
            mAMap = mAMapNaviView.getMap();
        }
        // 设置导航的属性和ui显示
        MapUtils.setNaviOptions(getContext(), mAMap, mAMapNaviView, mUserRepository);
        mAMapNaviView.setNaviMode(AMapNaviView.NORTH_UP_MODE);
        mAMapNaviView.setTrafficLine(true);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        DaggerANavigateComponent.builder()
                .appComponent(getAppComponent())
                .aNavigateModule(new ANavigateModule(this))
                .build()
                .inject(this);
    }

    @Override
    public void onResume() {
        super.onResume();
        mAMapNaviView.onResume();
        mPresenter.subscribe();
    }

    @Override
    public void onPause() {
        super.onPause();
        mAMapNaviView.onPause();
        mPresenter.unsubscribe();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mAMapNaviView.onDestroy();
        mPresenter.onDestory();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        isCycle = false;
        mAMapNavi.stopAimlessMode();
        mAMapNavi.stopNavi();
        mAMapNavi.destroy();
    }

    /**
     * 设置交通路况的显示
     *
     * @param showTrafficLine
     */
    @Override
    public void showTrafficLine(boolean showTrafficLine) {
        AMapNaviViewOptions options = mAMapNaviView.getViewOptions();
        options.setTrafficLine(showTrafficLine);//设置是否绘制显示交通路况的线路（彩虹线），拥堵-红色，畅通-绿色，缓慢-黄色，未知-蓝色。
        options.setTrafficInfoUpdateEnabled(showTrafficLine);//设置是否显示道路信息 View
        mAMapNaviView.setViewOptions(options);
    }

    /**
     * 设置上边距和下边距
     *
     * @param top
     * @param bottom
     */
    @Override
    public void setMapPadding(int top, int bottom) {
        mTop = top;
        mBottom = bottom;
    }

    /**
     * 定位到车辆位置
     *
     * @param center
     */
    @Override
    public void locate(LatLng center) {
        if (center == null) return;
        mAMap.animateCamera(CameraUpdateFactory.changeLatLng(center));
    }

    @Override
    public void calculateRoute(LatLng origin, LatLng dest) {

    }

    /**
     * 导航
     *
     * @param origin
     * @param dest
     */
    @Override
    public void navigate(LatLng origin, LatLng dest) {
        if (mNaviDest != null
                && mNaviDest.latitude == dest.latitude
                && mNaviDest.longitude == dest.longitude)
            return; //相同坐标点，不重新开启导航

        sList.clear();
        eList.clear();
        mNaviOrigin = origin;
        mNaviDest = dest;
        sList.add(new NaviLatLng(mNaviOrigin.latitude, mNaviOrigin.longitude));
        eList.add(new NaviLatLng(mNaviDest.latitude, mNaviDest.longitude));
        if (mIsNaviInited) onInitNaviSuccess(); //开启导航
    }

    /**
     * 设置导航路线的起终点
     *
     * @param origin
     * @param dest
     */
    @Override
    public void setOrderPoint(LatLng origin, LatLng dest) {
        mOrderOrigin = origin;
        mOrderDest = dest;
    }

    /**
     * 实时更新导航信息
     *
     * @param naviInfo
     */
    @Override
    public void postNaviInfo(NaviInfo naviInfo) {
        if (naviInfo == null) return;
        EventBus.getDefault().post(new MapEvent(MapEvent.VIEW_NAVI_INFO_UPDATE, naviInfo)); //通知其它界面，刷新距离和时间显示
    }

    /**
     * 设置模拟导航
     *
     * @param isEmulator
     */
    @Override
    public void emulator(boolean isEmulator) {
        mEmulator = isEmulator;
        if (mIsNaviInited) onInitNaviSuccess();
    }

    /**
     * 巡航
     *
     * @param curLatLng
     */
    @Override
    public void cruise(LatLng curLatLng) {
        isCycle = true;
        //停止导航
        mAMapNavi.stopNavi();
        //清除地图（清除上一次的导航记录,只清除一次）
        mAMap.clear();
        //开启巡航模式
        mAMapNavi.startAimlessMode(AimLessMode.CAMERA_AND_SPECIALROAD_DETECTED);

        //先移除所有小车
        mMapUtils.removeCars();
        //添加移动小车
        Car car = new Car();
        car.setId("10000");
        car.setLat(curLatLng.latitude);
        car.setLng(curLatLng.longitude);
        car.setAngle(curAngle);

        car.setResId(R.drawable.map_icon_car);

        mMapUtils.moveCar(car, mAMap);

        Observable.timer(800, TimeUnit.MILLISECONDS)
                .compose(RxUtil.applySchedulers())
                .subscribe(aLong -> mAMap.animateCamera(
                        CameraUpdateFactory.newCameraPosition(new CameraPosition(curLatLng, 15, 0, 0)), 800, null),
                        KLog::e);
    }

    //只显示订单起点
    @Override
    public void showOrigin(LatLng origin) {
        if (origin != null)
            MapUtils.setOriginMarker(getContext(), origin, mAMap);
    }

    //只显示订单终点
    @Override
    public void showDest(LatLng dest) {
        if (dest != null)
            MapUtils.setEndMarker(getContext(), dest, mAMap);
    }

    /**
     * 地图层初始化完成（高德自身回调方法）
     */
    @Override
    public void onInitNaviSuccess() {
        super.onInitNaviSuccess();
        //巡航状态下不执行导航计算
        if (isCycle) return;

        mIsNaviInited = true; //已初始化
        if (sList.isEmpty() || eList.isEmpty()) return;

        mAMap.clear();
        mAMapNavi.stopNavi(); //先停止导航
        EventBus.getDefault().post(new MapEvent(MapEvent.VIEW_RESET)); //通知其它界面，重置距离和时间显示
        int strategy = 0;
        try {
            //开始导航路径计算，再次强调，最后一个参数为true时代表多路径，否则代表单路径
            strategy = mAMapNavi.strategyConvert(false, false, false, false, false);
        } catch (Exception e) {
            e.printStackTrace();
        }
        mAMapNavi.calculateDriveRoute(sList, eList, null, strategy);
    }

    @Override
    public void onCalculateRouteSuccess(int[] ints) {
        super.onCalculateRouteSuccess(ints);
        if (isCycle) return;

        postNaviInfo(mAMapNavi.getNaviInfo());
        /* 只有测试版本，可以模拟导航 */
        int naviType = (mEmulator && BuildConfig.DEBUG) ? NaviType.EMULATOR : NaviType.GPS;
        mAMapNavi.startNavi(naviType);
    }

    /**
     * 导航信息实时更新（高德自身回调方法）
     *
     * @param naviInfo
     */
    @Override
    public void onNaviInfoUpdate(NaviInfo naviInfo) {
        super.onNaviInfoUpdate(naviInfo);
        if (isCycle) return;
        postNaviInfo(naviInfo);
    }

    /**
     * 获得实时定位（高德自身回调方法）
     *
     * @param aMapNaviLocation
     */
    @Override
    public void onLocationChange(AMapNaviLocation aMapNaviLocation) {
        super.onLocationChange(aMapNaviLocation);
        KLog.i(aMapNaviLocation.getCoord().getLatitude() + "," + aMapNaviLocation.getCoord().getLongitude());
        curAngle = aMapNaviLocation.getBearing();
        //实时传递位置信息
        EventBus.getDefault().post(new MapEvent(MapEvent.VIEW_LOCATION_CHANGE, aMapNaviLocation));
        if (isCycle) {//巡航状态下，在地图上显示小车位置
            LatLng latLng = new LatLng(aMapNaviLocation.getCoord().getLatitude(),
                    aMapNaviLocation.getCoord().getLongitude());
            //添加移动小车
            Car car = new Car();
            car.setId("10000");
            car.setLat(latLng.latitude);
            car.setLng(latLng.longitude);
            car.setAngle(curAngle);

            car.setResId(R.drawable.map_icon_car);

            mMapUtils.moveCar(car, mAMap);
            //屏幕移动到小车位置
            mAMap.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(latLng, 15, 0, 0)), 800, null);
        }
    }

    @Override
    public void onNaviMapMode(int i) {
        if (i == 1) {
            if (mSubscribe != null && !mSubscribe.isUnsubscribed()) {
                mSubscribe.unsubscribe();
            }
            mSubscribe = Observable.timer(5, TimeUnit.SECONDS)
                    .compose(RxUtil.applySchedulers())
                    .subscribe(aLong -> mAMapNaviView.recoverLockMode(),
                            KLog::e);
        }
    }
}
